package com.ethink.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.db.SuperEntity;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.system.api.constant.SystemRespCode;
import com.ethink.system.api.info.SystemOrganizationInfo;
import com.ethink.system.api.request.OrganizationAddRequest;
import com.ethink.system.api.request.OrganizationPageQueryRequest;
import com.ethink.system.api.request.OrganizationQueryRequest;
import com.ethink.system.api.request.OrganizationUpdateRequest;
import com.ethink.system.common.entity.SystemOrganization;
import com.ethink.system.common.entity.SystemUser;
import com.ethink.system.common.entity.SystemUserOrg;
import com.ethink.system.common.mapper.SystemOrganizationMapper;
import com.ethink.system.common.mapper.SystemUserOrgMapper;
import com.ethink.system.converter.SystemOrganizationConverter;
import com.ethink.system.service.SystemOrganizationService;
import com.ethink.system.service.SystemUserOrgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 系统组织机构表 Service接口实现
 *
 * @author default
 * @date 2022-09-26
 */
@Slf4j
@Service
public class SystemOrganizationServiceImpl implements SystemOrganizationService {

    @Autowired
    private SystemOrganizationMapper systemOrganizationMapper;

    @Autowired
    private SystemUserOrgMapper systemUserOrgMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(OrganizationAddRequest request) {
        //查询父id是否存在
        LambdaQueryWrapper<SystemOrganization> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SystemOrganization::getParentOrgId, request.getParentOrgId());
        wrapper.eq(SystemOrganization::getOrgName, request.getOrgName());
        List<SystemOrganization> organizationList = systemOrganizationMapper.selectList(wrapper);
        if (CollUtil.isNotEmpty(organizationList)) {
            throw new BusinessException(SystemRespCode.ORGANIZATION_NAME_IS_REPEAT);
        }
        SystemOrganization systemOrganization = BeanUtil.copyProperties(request, SystemOrganization.class);
        systemOrganizationMapper.insert(systemOrganization);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(OrganizationUpdateRequest request) {
        SystemOrganization systemOrganization = systemOrganizationMapper.selectById(request.getId());
        if (ObjectUtil.isEmpty(systemOrganization)) {
            throw new BusinessException(SystemRespCode.ORGANIZATION_ID_IS_NOT_EXIST);
        }
        LambdaQueryWrapper<SystemOrganization> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SystemOrganization::getParentOrgId, systemOrganization.getParentOrgId());
        wrapper.eq(SystemOrganization::getOrgName, request.getOrgName());
        List<SystemOrganization> organizationList = systemOrganizationMapper.selectList(wrapper);
        if (CollUtil.isNotEmpty(organizationList)) {
            throw new BusinessException(SystemRespCode.ORGANIZATION_NAME_IS_REPEAT);
        }
        LambdaUpdateWrapper<SystemOrganization> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SystemOrganization::getId, request.getId())
                .set(SystemOrganization::getOrgName, request.getOrgName());
        systemOrganizationMapper.update(null, updateWrapper);
    }

    @Override
    public List<SystemOrganizationInfo> systemOrganizationGetAll(OrganizationQueryRequest request) {
        LambdaQueryWrapper<SystemOrganization> wrapper = new LambdaQueryWrapper();
        wrapper.eq(SuperEntity::getIsDeleted,true);
        if (StrUtil.isNotBlank(request.getOrgName())) {
            wrapper.eq(SystemOrganization::getOrgName, request.getOrgName());
        }
        if (StrUtil.isNotBlank(request.getCreateTimeBegin())) {
            wrapper.gt(SystemOrganization::getCreateTime, request.getCreateTimeBegin());
        }
        if (StrUtil.isNotBlank(request.getCreateTimeEnd())) {
            wrapper.lt(SystemOrganization::getCreateTime, request.getCreateTimeEnd());
        }
        List<SystemOrganization> organizationList = systemOrganizationMapper.selectList(wrapper);
        List<SystemOrganizationInfo> infoList = new ArrayList<>();
        SystemOrganizationConverter systemOrganizationConverter = new SystemOrganizationConverter();
        for (SystemOrganization systemOrganization : organizationList) {
            SystemOrganizationInfo systemOrganizationInfo = systemOrganizationConverter.convertFrom(systemOrganization);
            infoList.add(systemOrganizationInfo);
        }
        return infoList;
    }

    @Override
    public SystemOrganizationInfo getSystemOrganizationById(Long systemOrganizationId) {
        SystemOrganization systemOrganization = systemOrganizationMapper.selectById(systemOrganizationId);
        SystemOrganizationConverter systemOrganizationConverter = new SystemOrganizationConverter();
        SystemOrganizationInfo systemOrganizationInfo = systemOrganizationConverter.convertFrom(systemOrganization);
        return systemOrganizationInfo;
    }

    @Override
    public void systemOrganizationDelete(Long id) {
        //组织下挂了用户数据时不能删除
        checkOrgBindUser(id);
        //组织有下级组织时不能删除
        checkByChild(id);
        LambdaUpdateWrapper<SystemOrganization> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SystemOrganization::getId, id)
                .set(SystemOrganization::getIsDeleted, 1);
        this.systemOrganizationMapper.update(null, updateWrapper);
    }

    private void checkByChild(Long id) {
        LambdaQueryWrapper<SystemOrganization> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemOrganization::getParentOrgId,id);
        Integer count = systemOrganizationMapper.selectCount(queryWrapper);
        if (count > 0){
            throw new BusinessException(SystemRespCode.ORGANIZATION_HAVE_ITEM);
        }
    }


    private void checkOrgBindUser(Long id) {
        LambdaQueryWrapper<SystemUserOrg> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemUserOrg::getOrgId,id);
        Integer count = systemUserOrgMapper.selectCount(queryWrapper);
        if (count > 0){
            throw new BusinessException(SystemRespCode.ORGANIZATION_BIND_USER);
        }
    }

    @Override
    public Page<SystemOrganizationInfo> pageQuerySystemOrganization(OrganizationPageQueryRequest request) {
        return systemOrganizationMapper.pageQuerySystemOrganization(PageUtils.buildPage(request), request);
    }
}
